package com.his.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.his.entity.dto.*;
import com.his.mapper.*;
import com.his.service.IRegisterService;
import com.his.entity.vo.RegisterVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 挂号及退号Service业务层处理
 *
 * @author lixue
 * @date 2025-09-05
 */
@Service
public class RegisterServiceImpl extends ServiceImpl<RegisterMapper, Register> implements IRegisterService
{
    @Autowired
    private RegisterMapper registerMapper;
    @Autowired
    private DepartmentMapper departmentMapper;
    @Autowired
    private EmployeeMapper employeeMapper;
    @Autowired
    private RegistLevelMapper registLevelMapper;
    @Autowired
    private SettleCategoryMapper settleCategoryMapper;

    /**
     * 查询挂号及退号
     *
     * @param id 挂号及退号主键
     * @return 挂号及退号
     */
    @Override
    public Register selectRegisterById(Long id)
    {
        return registerMapper.selectRegisterById(id);
    }

    /**
     * 查询挂号及退号列表
     *
     * @param register 挂号及退号
     * @return 挂号及退号
     */
    @Override
    public List<RegisterVO> selectRegisterList(Register register)
    {

        // 1. 查询挂号主表数据
        List<Register> list = registerMapper.selectRegisterList(register);

        if (list.isEmpty()) {
            return new ArrayList<>();
        }

        // 2. 提取所有需要关联的 ID 列表
        List<Long> deptIds = list.stream().map(Register::getDeptmentId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
        List<Long> empIds = list.stream().map(Register::getEmployeeId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
        List<Long> levelIds = list.stream().map(Register::getRegistLevelId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
        List<Long> settleIds = list.stream().map(Register::getSettleCategoryId).filter(Objects::nonNull).distinct().collect(Collectors.toList());

        // 3. 并行查询各关联表（有效数据）
        Map<Long, String> deptMap = new HashMap<>();
        if (!deptIds.isEmpty()) {
            List<Department> depts = departmentMapper.selectList(
                    Wrappers.lambdaQuery(Department.class)
                            .in(Department::getId, deptIds)
                            .eq(Department::getDelmark, 1)
            );
            deptMap = depts.stream().collect(Collectors.toMap(Department::getId, Department::getDeptName));
        }

        Map<Long, String> empMap = new HashMap<>();
        if (!empIds.isEmpty()) {
            List<Employee> emps = employeeMapper.selectList(
                    Wrappers.lambdaQuery(Employee.class)
                            .in(Employee::getId, empIds)
                            .eq(Employee::getDelmark, 1)
            );
            empMap = emps.stream().collect(Collectors.toMap(Employee::getId, Employee::getRealName));
        }

        Map<Long, String> levelMap = new HashMap<>();
        if (!levelIds.isEmpty()) {
            List<RegistLevel> levels = registLevelMapper.selectList(
                    Wrappers.lambdaQuery(RegistLevel.class)
                            .in(RegistLevel::getId, levelIds)
                            .eq(RegistLevel::getDelmark, 1)
            );
            levelMap = levels.stream().collect(Collectors.toMap(RegistLevel::getId, RegistLevel::getRegistName));
        }

        Map<Long, String> settleMap = new HashMap<>();
        if (!settleIds.isEmpty()) {
            List<SettleCategory> settles = settleCategoryMapper.selectList(
                    Wrappers.lambdaQuery(SettleCategory.class)
                            .in(SettleCategory::getId, settleIds)
                            .eq(SettleCategory::getDelmark, 1)
            );
            settleMap = settles.stream().collect(Collectors.toMap(SettleCategory::getId, SettleCategory::getSettleName));
        }

        // 4. 转换为 VO 并填充所有名称字段
        List<RegisterVO> voList = new ArrayList<>();
        for (Register r : list) {
            RegisterVO vo = BeanUtil.toBean(r, RegisterVO.class);

            vo.setDeptment(deptMap.get(r.getDeptmentId()));
            vo.setEmployee(empMap.get(r.getEmployeeId()));
            vo.setRegistLevel(levelMap.get(r.getRegistLevelId()));
            vo.setSettleCategory(settleMap.get(r.getSettleCategoryId()));

            voList.add(vo);
        }
        return voList;



    }

    /**
     * 新增挂号及退号
     *
     * @param register 挂号及退号
     * @return 结果
     */
    @Override
    public int insertRegister(Register register)
    {
        return registerMapper.insert(register);
    }

    /**
     * 修改挂号及退号
     *
     * @param register 挂号及退号
     * @return 结果
     */
    @Override
    public int updateRegister(Register register)
    {
        return registerMapper.updateById(register);
    }

    /**
     * 批量删除挂号及退号
     *
     * @param ids 需要删除的挂号及退号主键
     * @return 结果
     */
    @Override
    public int deleteRegisterByIds(Long[] ids)
    {
        return registerMapper.deleteRegisterByIds(ids);
    }

    /**
     * 删除挂号及退号信息
     *
     * @param id 挂号及退号主键
     * @return 结果
     */
    @Override
    public int deleteRegisterById(Long id)
    {
        return registerMapper.deleteRegisterById(id);
    }

    /**
     * 查询部门列表
     *
     * @return 部门列表
     */
    @Override
    public List<Department> deptList() {
        return registerMapper.deptList();
    }

    /**
     * 查询挂号级别列表
     *
     * @return 挂号级别列表
     */
    @Override
    public List<RegistLevel> levelList() {
        return registerMapper.levelList();
    }

    /**
     * 查询医生排班列表
     *
     * @return 医生排班列表
     */
    @Override
    public List<Employee> doctorScheduleList(Long deptId, Date visitDate, Long registerLevelId) {

        return registerMapper.departmentList(deptId, visitDate, registerLevelId);
    }

    /**
     * 查询结算类别列表
     *
     * @return 结算类别列表
     */
    @Override
    public List<SettleCategory> settleCategoryList() {
        return registerMapper.settleCategoryList();
    }

    /**
     * 查询排班已用配额
     *
     * @return 排班已用配额
     */
    @Override
    public Map<String, Integer> scheduleUsedQuota(Long deptId, Date visitDate, Long registLevelId) {

        int count = registerMapper.selectRegisterCount(visitDate, deptId, registLevelId);
        return Map.of("usedQuota", count);
    }
}
